# Copyright (C) 2007 Laszlo Pandy <laszlok2@gmail.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Library General Public License for more details.
#
# You should have received a copy of the GNU Library General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.

import gtk
import pango
import decimal
Dec = decimal.Decimal

from AdventureMoney.core import Utils
import InterfaceUtils

class SummaryView(gtk.Frame):
	
	STYLE_BILL = (pango.WEIGHT_NORMAL, pango.STYLE_NORMAL)
	STYLE_TOTAL = (pango.WEIGHT_BOLD, pango.STYLE_NORMAL)
	STYLE_CATE = (pango.WEIGHT_NORMAL, pango.STYLE_ITALIC)
	
	def __init__(self, account):
		gtk.Frame.__init__(self)
		self.wTree = InterfaceUtils.GetGladeTree("SummaryViewHolder")
		
		signals = {
			"OnPeopleChanged" : self.OnComboChanged,
			"OnMonthChanged"  : self.OnComboChanged,
			"OnYearChanged"   : self.OnComboChanged
		}
		self.wTree.signal_autoconnect(signals)
		
		self.account = account
		self.account.connect("people", self.UpdateInterface)
		self.account.connect("categories", self.UpdateInterface)
		self.account.connect("bills", self.UpdateInterface)
		
		self.updating = False
		
		self.vbox = self.wTree.get_widget("SummaryViewVBox")
		self.wTree.get_widget("SummaryViewHolder").remove(self.vbox)
		self.add(self.vbox)
		
		self.treeview = self.wTree.get_widget("SummaryTreeView")
		types = (str,) * 7 + (pango.Weight, pango.Style)
		self.model = gtk.TreeStore(*types)
		self.treeview.set_model(self.model)
		
		insCol = self.treeview.insert_column_with_attributes
		Cell = gtk.CellRendererText
		insCol(-1, "Description", 	Cell(), text=0, weight=7, style=8)
		insCol(-1, "Amount Paid", 	Cell(), text=1, weight=7, style=8)
		insCol(-1, "Amount Shared", 	Cell(), text=2, weight=7, style=8)
		insCol(-1, "Date", 		Cell(), text=3, style=8)
		insCol(-1, "Value", 		Cell(), text=4, style=8)
		insCol(-1, "Paid By", 		Cell(), text=5, style=8)
		insCol(-1, "Shared By", 	Cell(), text=6, style=8)
		
		self.peopleCombo = self.wTree.get_widget("PeopleComboBox")
		self.peopleModel = gtk.ListStore(str, object)
		self.peopleCombo.set_model(self.peopleModel)
		self.peopleCombo.set_column_span_column(0)
		
		self.monthCombo = self.wTree.get_widget("MonthComboBox")
		
		self.yearCombo = self.wTree.get_widget("YearComboBox")
		self.yearModel = gtk.ListStore(str)
		self.yearCombo.set_model(self.yearModel)
		self.yearCombo.set_column_span_column(0)
		
		self.show_all()
		
	def OnComboChanged(self, widget):
		self.UpdateModel()
	
	@InterfaceUtils.UpdatingGUI
	def UpdateModel(self):
		self._UpdateModel()
		
	def _UpdateModel(self):
		self.model.clear()
		
		cateObjectDict = {None : []}
		billsList = self.GetFilteredBills()
		person = self.GetSelectedPerson()
		totalPValue = Dec(0)
		totalSValue = Dec(0)
		
		for cate in self.account.getCategories():
			cateObjectDict[cate] = []
		
		for bill in billsList:
			cate = bill.getCategory()
			cateObjectDict[cate].append(bill)
			
		categoryDict = {}
		for cate, billList in cateObjectDict.iteritems():
			if len(billList) == 0:
				# Don't display the category if there are no bills
				continue
			name = str(cate or "No Category")
			categoryDict[name] = billList
		
		for name in sorted(categoryDict.iterkeys()):
			cateBills = categoryDict[name]
			paid = self.account.totalPersonPaid(person, cateBills)
			shared = self.account.totalPersonShared(person, cateBills)
			totalPValue += paid
			totalSValue += shared
			pValue = "%.2f" % paid
			sValue = "%.2f" % shared
			
			t = (name, pValue, sValue, "", "", "", "") + self.STYLE_CATE
			self.model.append(None, t)
			
		pValue = "%.2f" % totalPValue
		sValue = "%.2f" % totalSValue
		t = ("Total", pValue, sValue, "", "", "", "")
		self.model.append(None, t + self.STYLE_TOTAL)
		
		treeIter = self.model.get_iter_root()
		iterList = []
		while treeIter:
			name = self.model.get_value(treeIter, 0)
				
			if categoryDict.has_key(name):
				iterList.append( (treeIter,categoryDict[name]) )
			
			treeIter = self.model.iter_next(treeIter)
		
		for treeIter, billsList in iterList:
			for bill in sorted(billsList):
				t = self.TupleFromBill(bill, person)
				self.model.append(treeIter, t)
	
	@InterfaceUtils.UpdatingGUI
	def UpdateInterface(self, widget=None):
		peopleIndex = self.peopleCombo.get_active()
		
		self.peopleModel.clear()
		for person in self.account.getPeople():
			self.peopleModel.append((str(person), person))
			
		if not 0 <= peopleIndex < len(self.peopleModel):
			peopleIndex = 0
		self.peopleCombo.set_active(peopleIndex)
		
		monthIndex = self.monthCombo.get_active()
		self.monthCombo.set_active(max(0, monthIndex))
		
		yearIndex = self.yearCombo.get_active()
		self.yearModel.clear()
		self.yearModel.append(("Any",))
		yearList = self.account.getBills().getYearList()
		yearList.sort()
		for year in yearList:
			self.yearModel.append( (str(year),) )
			
		if not 0 <= yearIndex < len(self.yearModel):
			yearIndex = 0
		self.yearCombo.set_active(yearIndex)
		
		self._UpdateModel()
		
	def GetFilteredBills(self):
		billsListOne = self.account.getBills()
		
		monthIndex = self.monthCombo.get_active()
		yearIter = self.yearCombo.get_active_iter()
		year = self.yearModel.get_value(yearIter, 0)
		if monthIndex != 0 and year != "Any":
			yearIndex = int(year)
			billsListOne.filterByYearAndMonth(yearIndex, monthIndex)
		elif year != "Any":
			yearIndex = int(year)
			billsListOne.filterByYearAndMonth(yearIndex)
		elif monthIndex != 0:
			billsListOne.filterByMonth(monthIndex)
			
		billsListTwo = billsListOne.copy()
		
		person = self.GetSelectedPerson()
		if person:
			billsListOne.filterByPaidBy([person])
			billsListTwo.filterBySharedBy([person], billsListTwo.SHARED_ANY)
		
		billsListOne.extend(billsListTwo)
		return billsListOne
		
	def GetSelectedPerson(self):
		peopleIter = self.peopleCombo.get_active_iter()
		if peopleIter:
			return self.peopleModel.get_value(peopleIter, 1)
		
	def TupleFromBill(self, bill, person):
		desc = bill.getDetails()
		date = str(bill.getDate())
		value = str(bill.getValue())
		pBy = str(bill.getPaidBy())
		sBy = "---"
		pValue = "---"
		sValue = "---"
		
		if bill.getSharedBy():
			sBy = bill.getSharedBy().getPrettyString()
			sharedBy = bill.getSharedBy()
			if person in sharedBy:
				sValue = "%.2f" % sharedBy.calculatePersonShare(person, bill.getValue())
		if bill.getPaidBy() == person:
			pValue = "%.2f" % bill.getValue()
		
		return (desc, pValue, sValue, date, value, pBy, sBy) + self.STYLE_BILL
		
	def TupleFromCategory(self, cate, person, cateBills):
		name = str(cate or "No Category")
		pValue = "%.2f" % self.account.totalPersonPaid(person, cateBills)
		sValue = "%.2f" % self.account.totalPersonShared(person, cateBills)
		
		return (name, pValue, sValue, "", "", "", "") + self.STYLE_CATE
		
		
